#include "ssd1619.h"

// 初始化函数、全局刷新函数，以及清除屏幕的函数。
// ssd1619_display_full
// ssd1619_display_full
// ssd1619_init
// ssd1619_clear

// static uint8_t part_times = 0; 

/*------------------------------------------------------------*/



/*------------------------------------------------------------*/
/*SPI*/

void LCD_Writ_Bus(uint8_t dat)
{
    SSD1619_CS_Clr();
    //dt 
    spi_i2s_data_transmit(SPI3,dat);
    // STS
    while(spi_i2s_flag_get(SPI3, SPI_I2S_TDBE_FLAG) == RESET);  //transmit data buffer full
    while(spi_i2s_flag_get(SPI3, SPI_I2S_BF_FLAG) == SET);//not busy
    SSD1619_CS_Set();
}


/*------------------------------------------------------------*/
/*command data*/
void ssd1619_write_cmd (uint8_t cmd)
{
    SSD1619_CS_Clr();
    SSD1619_DC_Clr();  // command write
    LCD_Writ_Bus(cmd);
    SSD1619_CS_Set();
}

void ssd1619_write_data (uint8_t data)
{
    SSD1619_CS_Clr();
    SSD1619_DC_Set();  // data write
    LCD_Writ_Bus(data);
    SSD1619_CS_Set();
}

void ssd1619_write_cmd1data (uint8_t cmd, uint8_t dat1)
{
    SSD1619_CS_Clr();
    SSD1619_DC_Clr();  // command write
    LCD_Writ_Bus(cmd);
    SSD1619_DC_Set();  // data write
    LCD_Writ_Bus(dat1);
    SSD1619_CS_Set();
}

void ssd1619_write_cmd2data (uint8_t cmd, uint8_t dat1, uint8_t dat2)
{
    SSD1619_CS_Clr();
    SSD1619_DC_Clr();  // command write
    LCD_Writ_Bus(cmd);
    SSD1619_DC_Set();  // data write
    LCD_Writ_Bus(dat1);
    LCD_Writ_Bus(dat2);
    SSD1619_CS_Set();
}

void ssd1619_write_cmd3data (uint8_t cmd, uint8_t dat1, uint8_t dat2, uint8_t dat3)
{
    SSD1619_CS_Clr();
    SSD1619_DC_Clr(); // command write
    LCD_Writ_Bus(cmd);
    SSD1619_DC_Set();  // data write
    LCD_Writ_Bus(dat1);
    LCD_Writ_Bus(dat2);
    LCD_Writ_Bus(dat3);
    SSD1619_CS_Set();
}




/*------------------------------------------------------------*/
/*busy flag*/ 

void ssd1619_wait_busy(void)
{
    while (1)
    {
        if (SSD1619_BUSY() == 0)
            break;
        delay_ms(5);
    }
}

/*------------------------------------------------------------*/




void ssd1619_set_XY (uint16_t x, uint16_t y)
{
    /* ����� */
    ssd1619_write_cmd1data (0x4E, x / 8);      // Ĭ�� 0 X address counter
    ssd1619_write_cmd2data (0x4F, y, y >> 8);  // Ĭ�� 0 Y address counter
}

void ssd1619_set_ram_area (uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
{
    /* ����RAM��ʼ��Χ */
    ssd1619_write_cmd (0x44);     // X
    ssd1619_write_data (x1 / 8);  // start
    ssd1619_write_data (x2 / 8);
    ssd1619_write_cmd (0x45);      // Y
    ssd1619_write_data (y1);       // start-L at 00h
    ssd1619_write_data (y1 >> 8);  // start-H
    ssd1619_write_data (y2);       // end-L
    ssd1619_write_data (y2 >> 8);  // end-H
    ssd1619_set_XY (x1, y1);
}

// void ssd1619_send_to_ram (uint8_t *buf, uint8_t part)
// {
//     if (part & 1)
//     {
//         ssd1619_wait_busy();
//         ssd1619_set_XY (0, 0);     // ��ֹ���ص�ƫ��
//         ssd1619_write_cmd (0x24);  // write RAM for black(0)/white (1)
//         ssd1619_write_multi_data(buf, SSD1619_X_POINTS * SSD1619_Y_POINTS / 8);
//     }

//     if (part & 2)  // Ϊ��ˢ��������
//     {
//         ssd1619_wait_busy();
//         ssd1619_set_XY (0, 0);     // ��ֹ���ص�ƫ��
//         ssd1619_write_cmd (0x26);  // write RAM for black(0)/white (1)
//         ssd1619_write_multi_data (buf, SSD1619_X_POINTS * SSD1619_Y_POINTS / 8);
//     }
// }

/*----------------------------------------------------------*/
void ssd1619_deep_sleep (void)
{
    ssd1619_wait_busy();
    ssd1619_write_cmd1data (0x10, 0x01);  // Display Update Control
}

// void ssd1619_display_part (uint8_t *buf)
// {
//     if (part_times > SSD1619_MAX_PART)  // �����������ˢ����
//     {
//         ssd1619_display_full (buf);
//         part_times = 0;
//     }
//     else
//     {
//         LCD_Init (1);
//         ssd1619_send_to_ra(buf, 1);
//         // ssd1619_write_cmd1data (0x22, 0x0C);
//         ssd1619_write_cmd (0x20);
//         ssd1619_wait_busy();
//         ssd1619_send_to_ram(buf, 1);
//         ssd1619_deep_sleep();
//         part_times++;
//     }
// }

// void ssd1619_display_full (uint8_t *buf)
// {
//     LCD_Init (0);//修改
//     ssd1619_send_to_ram (buf, 1 | 2);
//     ssd1619_write_cmd1data (0x22, 0xC7);
//     ssd1619_write_cmd (0x20);
//     ssd1619_wait_busy();
//     ssd1619_send_to_ram (buf, 2);
//     ssd1619_deep_sleep();
//     part_times = 0;
// }


/*----------------------------------------------------------*/
void LCD_Clear(uint16_t Color){
	uint16_t i,j;  	
	ssd1619_set_ram_area(0,0,LCD_W-1,LCD_H-1);//设定左上右下位置
    for(i=0;i<LCD_W;i++)
	 {
	  for (j=0;j<LCD_H;j++)
	   	{
        	ssd1619_write_data(Color);	 			 
	    }
	  }
}

/*----------------------------------------------------------*/

void LCD_Init(uint8_t mode_part){

    /*---------------*/
    SSD1619_RST_Clr();
    delay_ms(300);
    SSD1619_RST_Set();
    delay_ms(300);
    /*---------------*/

    /* Start Initial Sequence*/
    ssd1619_write_cmd (0x12);  // SW Reset
    ssd1619_wait_busy();

    ssd1619_write_cmd1data (0x74, 0x54);  // Set Analog Block Control
    ssd1619_write_cmd1data (0x7e, 0x3B);


    ssd1619_write_cmd3data (0x01, 0x2b, 0x01, 0x00);  // 300 mux,Y�Ƿ�ת

    ssd1619_write_cmd (0x0C);   //
    ssd1619_write_data (0x8B);  //
    ssd1619_write_data (0x9C);  //
    ssd1619_write_data (0xD6);  //
    ssd1619_write_data (0x0F);  //
    
    ssd1619_write_cmd1data (0x2C, 0X00);  // VCOM Voltage
    ssd1619_wait_busy();
    
    /* Ƶ������ */
    ssd1619_write_cmd1data (0x3A, 0x21);  // 50Hz
    ssd1619_write_cmd1data (0x3B, 0x06);  // 50Hz-���˱�ǳ
    ssd1619_write_cmd1data (0x3C, 0x03);

    /* ��ˢ��� */
    ssd1619_write_cmd1data (0x21, 0x40);  // 
    
    /* XY���������� */
    ssd1619_write_cmd1data (0x11, 0x03);  // bit0-1:X��Y����(1)���ǵݼ�(0)

    /* ����RAM��ʼ��Χ */
    ssd1619_write_cmd (0x44);   // X
    ssd1619_write_data (0x00);  // start = 0
    ssd1619_write_data (0x31);  // end = 400(line) / 8 - start - 1
    ssd1619_write_cmd (0x45);   // Y
    ssd1619_write_data (0x00);  // end-L at 00h
    ssd1619_write_data (0x00);  // end-H
    ssd1619_write_data (0x2B);  // start-L
    ssd1619_write_data (0x01);  // start-H

    /* XY������ */
    ssd1619_write_cmd1data (0x4E, 0x00);        // Ĭ�� 0 X address counter
    ssd1619_write_cmd2data (0x4F, 0x00, 0x00);  // Ĭ�� 0 Y address counter

    /* �¶ȴ����� */
    ssd1619_write_cmd1data (0x18, 0x80);  // �ڲ��¶ȴ�����

    ssd1619_write_cmd (0x37);  // ΢ѩ��û��ˢ�»���Ӱ
    ssd1619_write_data (0x00);
    ssd1619_write_data (0x00);
    ssd1619_write_data (0x00);
    ssd1619_write_data (0x00);
    ssd1619_write_data (0x80);
    ssd1619_write_cmd1data (0X22, 0XC7);
    ssd1619_wait_busy();
}
